package data_source.DAO.jdbc;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import util.Conexao;
import util.DefaultException;

/**
 * Classe que implementa métodos genéricos de consultas ao banco de dados
 * @author Owner
 */
public class GeralDAO extends Conexao{
    private String table;
    private String individual;
    
    /**
     * Construtor da classe, define o nome da tabela a se pesquisar e uma string a ser imprimida
     * @param type string com o nome da tabela (sem um 's') para que seja mais fácil imprimir informações
     */
    public GeralDAO(String type){
	this.table = type+"s";
	this.individual = type;
    }
    
    /**
     * Pesquisa tudo de uma tabela
     * @return conjunto não tratado de informações retornadas
     */
    public ResultSet consultALL(){
	return consultItemALL("*");
    }
    
    /**
     * Pesquisa por um item específico em uma tabela
     * @param item informação a ser procurada
     * @return conjunto não tratado de informações retornadas
     */
    public ResultSet consultItemALL(String item){
	String sql = "SELECT "+item+" FROM "+table;
	return consultaToResultSet(sql);
    }
        
    /**
     * Consulta de seleção com uma restrição no "where"
     * @param data informação procurada
     * @param tipo tipo da restrição
     * @param item informação da restrição
     * @return conjunto não tratado de informações retornadas
     */
    public ResultSet getDataFromItem(String data, String tipo, String item){
	String sql = "SELECT "+data+" FROM "+table+" WHERE "+tipo+" = "+item;
	return consultaToResultSet(sql);
    }
    
    /**
     * Consulta de seleção com duas restrições no "where"
     * @param data informação procurada
     * @param tipo1 tipo da restrição
     * @param item1 informação da restrição
     * @param tipo2 tipo da restrição
     * @param item2 informação da restrição
     * @return conjunto não tratado de informações retornadas
     */
    public ResultSet getDataFrom2Item(String data, String tipo1, String item1, String tipo2, String item2){
	String sql = "SELECT "+data+" FROM "+table+" WHERE "+tipo1+" = "+item1+" AND "+tipo2+" = "+item2;
	return consultaToResultSet(sql);
    }
 
    /**
     * Pega a quantidade de registros de uma coluna específica
     * @param item coluna específica
     * @return quantidade de registros de uma coluna específica
     */
    public int getCountItem(String item){
	String sql = "SELECT COUNT("+item+") AS QTD FROM "+table;
	return consultaToInt(sql, "QTD");
    }
    
    /**
     * Recupera um dado inteiro de uma dada coluna da tabela
     * @param data coluna da tabela pesquisada
     * @param tipo tipo da pesquisa que será realizada
     * @param item variável do tipo que será pesquisado
     * @return um inteiro indicando se achou ou não
     */
    public int getIntFromItem(String data, String tipo, String item){
	String sql = "SELECT "+data+" FROM "+table+" WHERE "+tipo+" = '"+item+"'";
	return consultaToInt(sql, data);
    }
    
    /**
     * Recupera uma string de uma dada coluna da tabela
     * @param data coluna que será pesquisada a informação
     * @param tipo o tipo que será pesquisado
     * @param item um código do tipo que será pesquisado
     * @return string indicando o valor encontrado ou um null, caso não encontre
     */
    public String getStringFromItem(String data, String tipo, String item){
	String sql = "SELECT "+data+" FROM "+table+" WHERE "+tipo+" = '"+item+"'";
	return consultaToString(sql,data);
    }
    
    /**
     * Pega o último item introduzido na tabela
     * @param item coluna que será utilizada
     * @return string
     */
    public String getLast(String item){
	String sql = "SELECT "+item+" AS MAX FROM "+table+" ORDER BY "+item+" DESC LIMIT 1";
	return consultaToString(sql,"MAX");
    }
    
    /**
     * Recupera strings de uma dada coluna da tabela
     * @param data coluna que será pesquisada a informação
     * @param tipo tipo que será pesquisado
     * @param item um código do tipo que será pesquisado
     * @return um conjunto de strings indicando o valor encontrado ou um null, caso não encontre
     */
    public String[] getStringsFromItem(String data, String tipo, String item){
	String sql = "SELECT "+data+" FROM "+table+" WHERE "+tipo+" = '"+item+"'";
	return	consultaToStrings(sql,data);
    }
    
    /**
     * Pega todos os resultados únicos de uma coluna específica
     * @param coluna coluna específica
     * @return vetor de strings únicas
     */
    public String[] distinctStrings(String coluna){
	String sql = "SELECT DISTINCT "+coluna+" FROM "+table;
	return consultaToStrings(sql,coluna);
    }
    
    public String[] getNomes(){
	ResultSet rs = consultItemALL("nome");
	String[] nomes = new String[getCountItem("nome")];
	
	try{
	    int i = 0;
	    while ( rs.next () ){
		nomes[i++] = rs.getString("nome");
	    }
	} catch (SQLException e) {
	    e.printStackTrace();
	    nomes = null;
	}
	return nomes;
    }   
    
    //CRUD Básico (sem SELECT)
    
    /**
     * 
     * @param sql
     * @throws DefaultException
     */
    public void include (String sql) throws DefaultException{ 
	try{
	    execute ( sql );
	} catch ( SQLException e){
	    e.printStackTrace();
	    throw new DefaultException("O "+individual+" não pode ser inserido!");
	}
    }
    
    /**
     * 
     * @param sql
     * @throws DefaultException
     */
    public void updateOne(String sql) throws DefaultException{
	try{
	    update ( sql );
	} catch ( SQLException e){
	    e.printStackTrace();
	    throw new DefaultException("O "+individual+" não pode ser atualizado!");
	}
    }
    
    /**
     * Remove um item da tabela
     * @param tipo da restrição
     * @param codigo identificador da restrição
     * @throws DefaultException imprime erro caso não seja possível remover
     */
    public void delete(String tipo, String codigo) throws DefaultException{
	String sql = "DELETE FROM "+table+" WHERE "+ tipo + " = '" + codigo + " '";
	try {
	    execute ( sql );
	} catch (SQLException e) {
	    e.printStackTrace();
	    throw new DefaultException(" Não foi possivel remover o "+individual+"!");
	}
    }
    
    //Funções Auxiliares
    
    private String[] consultaToStrings(String sql, String item){
	int qtd = 0, i = 0;
	ResultSet rs = null;
	System.out.println(sql);
	try {
	    rs = query( sql );
	    while(rs.next())
		qtd++;	    
	    String[] str = new String[qtd];
	    while(rs.previous()){
		str[i++] = rs.getString(item);
	    }
	    return str;
	} catch (SQLException ex) {
	    Logger.getLogger(GeralDAO.class.getName()).log(Level.SEVERE, null, ex);
	}
	return null;
    }

    private String consultaToString(String sql, String item){
	ResultSet rs = null;
	System.out.println(sql);
	try {
	    rs = query( sql );
	    if(rs.next())
		return rs.getString(item); 
	} catch (SQLException ex) {
	    System.out.println("ERRO");
	    //TODO ARRUMAR
	}
	return null;
    }
    
    private int consultaToInt(String sql, String item){
	ResultSet rs = null;
	try {
	    rs = query( sql );
	    if(rs.next())
		return rs.getInt(item); 
	} catch (SQLException ex) {
	    System.out.println("ERRO");
	}
	return 0;
    }
    
    public ResultSet consultaToResultSet(String sql){
	ResultSet rs = null;
	try {
	    rs = query( sql );
	} catch (SQLException e) {}
	return rs;
    }
}
